﻿/*  CamHelper (See http://camhelper.codeplex.com/ or https://bitbucket.org/AndiKS/camhelper for more Info)
    Copyright (C) 2011 Andreas Wimmer

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

using System;
using CamHelper.Interpreter;
using NUnit.Framework;

namespace CamHelper.Tests.Interpreter
{
    [TestFixture]
    public class ParameterFileLineTest
    {
        [Test, ExpectedException(typeof(ArgumentNullException))]
        public void Emtpy_ContentNull()
        {
            var line = new ParameterFileLine(null, 1, null);
        }

        [Test, ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void Emtpy_FileNumberNegativ()
        {
            var line = new ParameterFileLine(null, -1, String.Empty);
        }

        [Test]
        public void Empty()
        {
            var line = new ParameterFileLine(null, 0, String.Empty);

            Assert.AreEqual(line.LineNumber, 0);
            Assert.AreEqual(line.LineType, ParameterFileLineType.Empty);
            Assert.AreEqual(line.PureContent, String.Empty);

            Assert.AreEqual(line.Category, String.Empty);
            Assert.AreEqual(line.Comment, String.Empty);

            Assert.AreEqual(line.Key, String.Empty);
            Assert.AreEqual(line.Value, String.Empty);
            Assert.AreEqual(line.EmptyValue, true);
            Assert.AreEqual(line.ValueType, Char.MinValue);
        }

        [Test]
        public void Category()
        {
            var line = new ParameterFileLine(null, 5, "[automatic_phase]");

            Assert.AreEqual(line.File, null);
            Assert.AreEqual(line.LineNumber, 5);
            Assert.AreEqual(line.LineType, ParameterFileLineType.Category);
            Assert.AreEqual(line.PureContent, "[automatic_phase]");

            Assert.AreEqual(line.Category, "automatic_phase");
            Assert.AreEqual(line.Comment, String.Empty);

            Assert.AreEqual(line.Key, String.Empty);
            Assert.AreEqual(line.Value, String.Empty);
            Assert.AreEqual(line.EmptyValue, true);
            Assert.AreEqual(line.ValueType, Char.MinValue);
        }

        [Test]
        public void CategoryWithComment()
        {
            var line = new ParameterFileLine(null, 5, "[Par]		// Parameters");

            Assert.AreEqual(line.File, null);
            Assert.AreEqual(line.LineNumber, 5);
            Assert.AreEqual(line.LineType, ParameterFileLineType.Category);
            Assert.AreEqual(line.PureContent, "[Par]		// Parameters");

            Assert.AreEqual(line.Category, "Par");
            Assert.AreEqual(line.CategoryLower, "par");
            Assert.AreEqual(line.Comment, "Parameters");

            Assert.AreEqual(line.Key, String.Empty);
            Assert.AreEqual(line.Value, String.Empty);
            Assert.AreEqual(line.EmptyValue, true);
            Assert.AreEqual(line.ValueType, Char.MinValue);
        }

        [Test]
        public void KeyValue()
        {
            var line = new ParameterFileLine(null, 5, "# mini_variation = 0.2");

            Assert.AreEqual(line.File, null);
            Assert.AreEqual(line.LineNumber, 5);
            Assert.AreEqual(line.LineType, ParameterFileLineType.KeyValue);
            Assert.AreEqual(line.PureContent, "# mini_variation = 0.2");

            Assert.AreEqual(line.Category, String.Empty);
            Assert.AreEqual(line.Comment, String.Empty);

            Assert.AreEqual(line.Key, "mini_variation");
            Assert.AreEqual(line.Value, "0.2");
            Assert.AreEqual(line.EmptyValue, false);
            Assert.AreEqual(line.ValueType, Char.MinValue);
            Assert.AreEqual(line.IsLogicalAnd, false);
        }

        [Test]
        public void KeyValueWithOutSpaceAfterNumberSign()
        {
            var line = new ParameterFileLine(null, 5, "#z_down_fr_in = .global.z_down_fr");

            Assert.AreEqual(line.File, null);
            Assert.AreEqual(line.LineNumber, 5);
            Assert.AreEqual(line.LineType, ParameterFileLineType.KeyValue);
            Assert.AreEqual(line.PureContent, "#z_down_fr_in = .global.z_down_fr");

            Assert.AreEqual(line.Category, String.Empty);
            Assert.AreEqual(line.Comment, String.Empty);

            Assert.AreEqual(line.Key, "z_down_fr_in");
            Assert.AreEqual(line.Value, ".global.z_down_fr");
            Assert.AreEqual(line.EmptyValue, false);
            Assert.AreEqual(line.ValueType, Char.MinValue);
            Assert.AreEqual(line.IsLogicalAnd, false);
        }

        [Test]
        public void KeyValueWithComment()
        {
            var line = new ParameterFileLine(null, 5, "# path_type = 1		// SHIFTED:0 CORRECTED:1 ORIGINAL:2");

            Assert.AreEqual(line.File, null);
            Assert.AreEqual(line.LineNumber, 5);
            Assert.AreEqual(line.LineType, ParameterFileLineType.KeyValue);
            Assert.AreEqual(line.PureContent, "# path_type = 1		// SHIFTED:0 CORRECTED:1 ORIGINAL:2");

            Assert.AreEqual(line.Category, String.Empty);
            Assert.AreEqual(line.Comment, "SHIFTED:0 CORRECTED:1 ORIGINAL:2");

            Assert.AreEqual(line.Key, "path_type");
            Assert.AreEqual(line.Value, "1");
            Assert.AreEqual(line.EmptyValue, false);
            Assert.AreEqual(line.ValueType, Char.MinValue);
        }

        [Test]
        public void KeyValueLargeWithComment()
        {
            var line = new ParameterFileLine(null, 5, "# dpas = (Tool.rad ==0 ) ? (Tool.diam *.75) : ((Tool.diam > 11) ? (Tool.diam - (Tool.rad * 2))* .75 : (Tool.diam - (Tool.rad * 2))* .9)		// overlap");

            Assert.AreEqual(line.File, null);
            Assert.AreEqual(line.LineNumber, 5);
            Assert.AreEqual(line.LineType, ParameterFileLineType.KeyValue);
            Assert.AreEqual(line.PureContent, "# dpas = (Tool.rad ==0 ) ? (Tool.diam *.75) : ((Tool.diam > 11) ? (Tool.diam - (Tool.rad * 2))* .75 : (Tool.diam - (Tool.rad * 2))* .9)		// overlap");

            Assert.AreEqual(line.Category, String.Empty);
            Assert.AreEqual(line.Comment, "overlap");

            Assert.AreEqual(line.Key, "dpas");
            Assert.AreEqual(line.Value, "(Tool.rad ==0 ) ? (Tool.diam *.75) : ((Tool.diam > 11) ? (Tool.diam - (Tool.rad * 2))* .75 : (Tool.diam - (Tool.rad * 2))* .9)");
            Assert.AreEqual(line.EmptyValue, false);
            Assert.AreEqual(line.ValueType, Char.MinValue);
        }

        [Test]
        public void KeyValueWithTypeValueEmpty()
        {
            var line = new ParameterFileLine(null, 5, "# Tool.Radius = L,");

            Assert.AreEqual(line.File, null);
            Assert.AreEqual(line.LineNumber, 5);
            Assert.AreEqual(line.LineType, ParameterFileLineType.KeyValue);
            Assert.AreEqual(line.PureContent, "# Tool.Radius = L,");

            Assert.AreEqual(line.Category, String.Empty);
            Assert.AreEqual(line.Comment, String.Empty);

            Assert.AreEqual(line.Key, "Tool.Radius");
            Assert.AreEqual(line.KeyLower, "tool.radius");
            Assert.AreEqual(line.Value, String.Empty);
            Assert.AreEqual(line.EmptyValue, true);
            Assert.AreEqual(line.ValueType, 'L');
        }

        [Test]
        public void KeyValueValueEmpty()
        {
            var line = new ParameterFileLine(null, 5, "# obstacle_height        =");

            Assert.AreEqual(line.File, null);
            Assert.AreEqual(line.LineNumber, 5);
            Assert.AreEqual(line.LineType, ParameterFileLineType.KeyValue);
            Assert.AreEqual(line.PureContent, "# obstacle_height        =");

            Assert.AreEqual(line.Category, String.Empty);
            Assert.AreEqual(line.Comment, String.Empty);

            Assert.AreEqual(line.Key, "obstacle_height");
            Assert.AreEqual(line.Value, String.Empty);
            Assert.AreEqual(line.EmptyValue, true);
            Assert.AreEqual(line.ValueType, Char.MinValue);
        }

        [Test]
        public void KeyValueValueEmptyWithoutWhitspace()
        {
            var line = new ParameterFileLine(null, 5, "# to_attack_type_str=");

            Assert.AreEqual(line.File, null);
            Assert.AreEqual(line.LineNumber, 5);
            Assert.AreEqual(line.LineType, ParameterFileLineType.KeyValue);
            Assert.AreEqual(line.PureContent, "# to_attack_type_str=");

            Assert.AreEqual(line.Category, String.Empty);
            Assert.AreEqual(line.Comment, String.Empty);

            Assert.AreEqual(line.Key, "to_attack_type_str");
            Assert.AreEqual(line.Value, String.Empty);
            Assert.AreEqual(line.EmptyValue, true);
            Assert.AreEqual(line.ValueType, Char.MinValue);
        }

        [Test]
        public void KeyValueWithTypeValueEmptyAnd()
        {
            var line = new ParameterFileLine(null, 5, "# Form.MachId = R,&,");

            Assert.AreEqual(line.File, null);
            Assert.AreEqual(line.LineNumber, 5);
            Assert.AreEqual(line.LineType, ParameterFileLineType.KeyValue);
            Assert.AreEqual(line.PureContent, "# Form.MachId = R,&,");

            Assert.AreEqual(line.Category, String.Empty);
            Assert.AreEqual(line.Comment, String.Empty);

            Assert.AreEqual(line.Key, "Form.MachId");
            Assert.AreEqual(line.Value, String.Empty);
            Assert.AreEqual(line.EmptyValue, true);
            Assert.AreEqual(line.ValueType, 'R');
            Assert.AreEqual(line.IsLogicalAnd, true);
        }

        [Test]
        public void KeyValueWithTypeValueEmptyWithComment()
        {
            var line = new ParameterFileLine(null, 5, "# depth_type = I,		// 0: TIP, 1:CYL, 2:GAUGE DIAM");

            Assert.AreEqual(line.File, null);
            Assert.AreEqual(line.LineNumber, 5);
            Assert.AreEqual(line.LineType, ParameterFileLineType.KeyValue);
            Assert.AreEqual(line.PureContent, "# depth_type = I,		// 0: TIP, 1:CYL, 2:GAUGE DIAM");

            Assert.AreEqual(line.Category, String.Empty);
            Assert.AreEqual(line.Comment, "0: TIP, 1:CYL, 2:GAUGE DIAM");

            Assert.AreEqual(line.Key, "depth_type");
            Assert.AreEqual(line.Value, String.Empty);
            Assert.AreEqual(line.EmptyValue, true);
            Assert.AreEqual(line.ValueType, 'I');
        }

        [Test]
        public void KeyValueWithTypeValue()
        {
            var line = new ParameterFileLine(null, 5, "# depth = L,.form_hole.depth");

            Assert.AreEqual(line.File, null);
            Assert.AreEqual(line.LineNumber, 5);
            Assert.AreEqual(line.LineType, ParameterFileLineType.KeyValue);
            Assert.AreEqual(line.PureContent, "# depth = L,.form_hole.depth");

            Assert.AreEqual(line.Category, String.Empty);
            Assert.AreEqual(line.Comment, String.Empty);

            Assert.AreEqual(line.Key, "depth");
            Assert.AreEqual(line.Value, ".form_hole.depth");
            Assert.AreEqual(line.EmptyValue, false);
            Assert.AreEqual(line.ValueType, 'L');
        }

        [Test]
        public void KeyValueWithTypeValueAndComment()
        {
            var line = new ParameterFileLine(null, 5, "# offset_side = L,.ComplexForm.22.Form.CheckBox.Value == 1 ? -0.5 : ( .ComplexForm.21.Form.CheckBox.Value == 1  ? .global.facing_offset_side-1 : -(Tool.diam*0.6))		// Depassement externe");

            Assert.AreEqual(line.File, null);
            Assert.AreEqual(line.LineNumber, 5);
            Assert.AreEqual(line.LineType, ParameterFileLineType.KeyValue);
            Assert.AreEqual(line.PureContent, "# offset_side = L,.ComplexForm.22.Form.CheckBox.Value == 1 ? -0.5 : ( .ComplexForm.21.Form.CheckBox.Value == 1  ? .global.facing_offset_side-1 : -(Tool.diam*0.6))		// Depassement externe");

            Assert.AreEqual(line.Category, String.Empty);
            Assert.AreEqual(line.Comment, "Depassement externe");

            Assert.AreEqual(line.Key, "offset_side");
            Assert.AreEqual(line.Value, ".ComplexForm.22.Form.CheckBox.Value == 1 ? -0.5 : ( .ComplexForm.21.Form.CheckBox.Value == 1  ? .global.facing_offset_side-1 : -(Tool.diam*0.6))");
            Assert.AreEqual(line.EmptyValue, false);
            Assert.AreEqual(line.ValueType, 'L');
        }

        [Test]
        public void KeyValueWithEmptyComment()
        {
            var line = new ParameterFileLine(null, 5, "# turn_rough_gros_ecret_security_distance = 0.2      //");

            Assert.AreEqual(line.File, null);
            Assert.AreEqual(line.LineNumber, 5);
            Assert.AreEqual(line.LineType, ParameterFileLineType.KeyValue);
            Assert.AreEqual(line.PureContent, "# turn_rough_gros_ecret_security_distance = 0.2      //");

            Assert.AreEqual(line.Category, String.Empty);
            Assert.AreEqual(line.Comment, "");

            Assert.AreEqual(line.Key, "turn_rough_gros_ecret_security_distance");
            Assert.AreEqual(line.Value, "0.2");
            Assert.AreEqual(line.EmptyValue, false);
            Assert.AreEqual(line.ValueType, Char.MinValue);
        }
    }
}
